/**
 * @author Stream
 * @date 2012 Jul 21, 2012 3:34:28 PM
 */
package com.boronstream.istar;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.boronstream.istar.SModel.SLayoutEnum;

/**
 * 
 * 
 */
public class Gen {

	private final static String FILE_S_NAME_PREFIX = "S";
	private final static String FILE_S_NAME = FILE_S_NAME_PREFIX + ".java";
	private final static String rootPath = "res/layout/";
	public static String PACKAGE_NAME = "com.boronstream.istar";
	// public static String SPATH = ".S";
	public static String XML_PRIFIX = "i";
	public static String XML_PRIFIX_C = "i";

	public static void main(String[] args) {
		// getLayoutFile
		File layoutDirectory = new File(rootPath);

		// layout files list
		String[] layoutFiels = layoutDirectory.list();

		// S.java
		StringBuffer stringBuffer = new StringBuffer("");

		/** Step1.block **/
		StringBuffer blockBuffer1 = new StringBuffer("/**\r\n"
				+ " * @author Stream\r\n" + " * @date " + new Date() + "\r\n"
				+ " */\r\n" + "package " + PACKAGE_NAME + ";\r\n\r\n"
				+ "import android.app.*;\r\n" + "import " + PACKAGE_NAME
				+ ".R;\r\n" + "import android.os.*;\r\n"
				+ "import android.view.*;\r\n" + "import android.widget.*;\r\n"
				+ "import android.webkit.*;\r\n"
				+ "import android.support.v4.app.FragmentActivity;\r\n"
				+ "import android.content.Context;\r\n"
				+ "import android.widget.RelativeLayout.LayoutParams;\r\n"
				+ "public interface " + FILE_S_NAME_PREFIX + " {\r\n");
		StringBuffer blockBuffer2 = new StringBuffer("");
		StringBuffer blockBuffer3 = new StringBuffer("}\r\n");

		/** Step2.iterator the layoutfields */
		for (String fileName : layoutFiels) {

			SModel sLayout = new SModel();

			// 
			if (fileName.startsWith(SLayoutEnum.ACTIVITY.typeNative)) {
				sLayout.setLayoutType(SLayoutEnum.ACTIVITY);
			} 
			else if (fileName.startsWith(SLayoutEnum.ACTIVITYF.typeNative)) {
				sLayout.setLayoutType(SLayoutEnum.ACTIVITYF);
			} 
			else if (fileName.startsWith(SLayoutEnum.ACTIVITYS.typeNative)) {
				sLayout.setLayoutType(SLayoutEnum.ACTIVITYS);
			} else if (fileName.startsWith(SLayoutEnum.ITEM.typeNative)) {
				sLayout.setLayoutType(SLayoutEnum.ITEM);
			} else if (fileName.startsWith(SLayoutEnum.TITLEBAR.typeNative)) {
				sLayout.setLayoutType(SLayoutEnum.TITLEBAR);
			} else {
				continue;
			}

			System.out.println("=====================File:" + fileName
					+ "==========================");

			String xmlName = fileterString(fileName);// 
			HashMap<String, String> activityFields = new HashMap<String, String>();
			readFile(xmlName, activityFields, sLayout);
			sLayout.setXMLName(xmlName);
			sLayout.setJavaFields(activityFields);
			blockBuffer2.append(sLayout.getContentString());
			// System.out.println("activity:"+s.getActivityName()+" xmlName="+xmlName);
			// System.out.println(s.getContentString());
		}

		/** Step3.make the content together */
		stringBuffer.append(blockBuffer1);
		stringBuffer.append(blockBuffer2);
		stringBuffer.append(blockBuffer3);
		System.out.println(stringBuffer);

		/** Step4.Write content into file */
		writeFile(stringBuffer, PACKAGE_NAME, FILE_S_NAME);
	}

	/**
	 * Write content into file
	 * 
	 * @param content
	 * @param packageName
	 * @param fileName
	 */
	private static void writeFile(StringBuffer content, String packageName,
			String fileName) {
		if (packageName == null) {
			System.err.println("packageName is Null");
			return;
		}

		// 
		StringBuffer filePath = new StringBuffer("");
		packageName = packageName.replace(".", "/");
		filePath.append("iphone/");
		filePath.append(packageName);
		new File(filePath.toString()).mkdirs();
		filePath.append("/" + fileName);
		File tempFile = new File(filePath.toString());
		if (tempFile.exists()) {
			tempFile.delete();
		}

		try {
			File file = new File(filePath.toString());
			if (!file.exists()) {
				file.createNewFile();
			}
			OutputStream outStream = new BufferedOutputStream(
					new FileOutputStream(file));
			outStream.write(content.toString().getBytes());
			outStream.close();
			System.out.println("write files finished its ok");
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	/**
	 * Read content from file
	 * 
	 * @param xmlName
	 * @param activityFields
	 * @param sLayout
	 */
	public static void readFile(String xmlName,
			HashMap<String, String> activityFields, SModel sLayout) {
		// System.out.println("**************readFile:" + xmlName
		// + "**************");
		SAXReader reader = new SAXReader();
		Document doc;
		try {
			doc = reader.read(new File(rootPath + xmlName + ".xml"));
			Element root = doc.getRootElement();
			String rootName = root.getName();
			// System.out.println("root:" + rootName);
			List<Attribute> rootAttributes = root.attributes();
			for (Attribute attribute : rootAttributes) {
				String spacePrefix = attribute.getNamespacePrefix();
				String name = attribute.getName();
				String idOriginal = attribute.getValue();
				String idNew = fileterString(idOriginal);

				// if the item can be translated into java code
				if ("android:id".equals((spacePrefix + ":" + name)
						.toLowerCase())
						&& !idOriginal.contains("@id")
						&& !idOriginal.contains("android:")) {
					try {
						activityFields.put(idNew, rootName);
					} catch (Exception e) {
						System.err.println("putError:id=" + idOriginal
								+ ",className=" + rootName);
						e.printStackTrace();
					}
					// System.out
					// .println(root spacePrefix + ":" + name + " = " + value);
					// break;
				}

				if ("stream:theme=titlebar".endsWith(spacePrefix + ":" + name
						+ "=" + idOriginal)) {
					sLayout.setThemeTitleBarUsed(true);
					readFile(XML_PRIFIX + "_titlebar", activityFields, sLayout);
				}
			}
			iteratorElement(root, activityFields, sLayout);
		} catch (Exception e) {
			e.printStackTrace();
		}
	};

	/**
	 * 
	 * @param root
	 *            rootLayout,LinearLayou,RelativeLayout,etc.
	 * @param activityFields
	 *            the data structor to save java fields
	 * @param sLayout
	 *            layoutMode,activity,item,etc.
	 */
	public static void iteratorElement(Element root,
			HashMap<String, String> activityFields, SModel sLayout) {
		for (Iterator<Element> iterator = root.elementIterator(); iterator
				.hasNext();) {
			Element element = (Element) iterator.next();
			String elementName = element.getName();
			// System.out.println("-----------------------------");

			// include files will be translate into javaCode
			if ("include".equals(elementName)) {
				String layoutName = element.attribute("layout").getValue();
				layoutName = fileterString(layoutName);
				readFile(layoutName, activityFields, sLayout);
			}

			// System.out.println(elementName);
			List<Attribute> listAttributes = element.attributes();
			// iterator the attributes
			for (Attribute attribute : listAttributes) {
				String spacePrefix = attribute.getNamespacePrefix();
				String name = attribute.getName();
				String idOriginal = attribute.getValue();
				String idNew = fileterString(idOriginal);
				if ("android:id".equals((spacePrefix + ":" + name)
						.toLowerCase())
						&& !idOriginal.contains("@id")
						&& !idOriginal.contains("android:")) {
					try {
						activityFields.put(idNew, elementName);
					} catch (Exception e) {
						System.err.println("putError:id=" + idNew
								+ ",className=" + elementName);
						System.err.println("putError:" + e);
					}
					// System.out
					// .println(spacePrefix + ":" + name + " = " + value);
					break;
				}
			}
			iteratorElement(element, activityFields, sLayout);
		}
	}

	/**
	 * get the id from xml resource beside the '@+id','@layout',etc.
	 * 
	 * @param string
	 * @return
	 */
	private static String fileterString(String string) {
		String[] filters = { "@+id/", "@id/", "@layout/", "@+layout", ".xml" };
		for (String filter : filters) {
			string = string.replace(filter, "");
		}
		return string;
	}
}
